home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus 2002 #3 / Amiga Plus CD - 2002 - No. 03.iso / AmiSoft / Hard / Drivr / 3c589.lha / 3c589 / Source / request.c < prev    next >
C/C++ Source or Header  |  2003-01-26  |  28KB  |  1,520 lines

  1. /*
  2.  
  3. File: request.c
  4. Author: Neil Cafferkey
  5. Copyright (C) 2001-2003 Neil Cafferkey
  6.  
  7. This program is free software; you can redistribute it and/or modify
  8. it under the terms of the GNU General Public License as published by
  9. the Free Software Foundation; either version 2 of the License, or
  10. (at your option) any later version.
  11.  
  12. This program is distributed in the hope that it will be useful, but
  13. WITHOUT ANY WARRANTY; without even the implied warranty of
  14. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  15. General Public License for more details.
  16.  
  17. You should have received a copy of the GNU General Public License
  18. along with this program; if not, write to the Free Software
  19. Foundation, Inc., 59 Temple Place - Suite 330, Boston,
  20. MA 02111-1307, USA.
  21.  
  22. */
  23.  
  24.  
  25. #include <exec/types.h>
  26. #include <exec/errors.h>
  27. #include "initializers.h"
  28. #include <devices/newstyle.h>
  29.  
  30. #include <proto/exec.h>
  31. #include <proto/utility.h>
  32.  
  33. #include "device.h"
  34.  
  35. #include "request_protos.h"
  36. #include "unit_protos.h"
  37.  
  38.  
  39. #define KNOWN_EVENTS (S2EVENT_ERROR|S2EVENT_TX|S2EVENT_RX|S2EVENT_ONLINE|\
  40.    S2EVENT_OFFLINE|S2EVENT_BUFF|S2EVENT_HARDWARE|S2EVENT_SOFTWARE)
  41.  
  42.  
  43. static BOOL CmdInvalid(struct IOSana2Req *request,struct DevBase *base);
  44. static BOOL CmdRead(struct IOSana2Req *request,struct DevBase *base);
  45. static BOOL CmdWrite(struct IOSana2Req *request,struct DevBase *base);
  46. static BOOL CmdFlush(struct IORequest *request,struct DevBase *base);
  47. static BOOL CmdS2DeviceQuery(struct IOSana2Req *request,
  48.    struct DevBase *base);
  49. static BOOL CmdGetStationAddress(struct IOSana2Req *request,
  50.    struct DevBase *base);
  51. static BOOL CmdConfigInterface(struct IOSana2Req *request,
  52.    struct DevBase *base);
  53. static BOOL CmdBroadcast(struct IOSana2Req *request,
  54.    struct DevBase *base);
  55. static BOOL CmdTrackType(struct IOSana2Req *request,
  56.    struct DevBase *base);
  57. static BOOL CmdUntrackType(struct IOSana2Req *request,
  58.    struct DevBase *base);
  59. static BOOL CmdGetTypeStats(struct IOSana2Req *request,
  60.    struct DevBase *base);
  61. static BOOL CmdGetSpecialStats(struct IOSana2Req *request,
  62.    struct DevBase *base);
  63. static BOOL CmdGetGlobalStats(struct IOSana2Req *request,
  64.    struct DevBase *base);
  65. static BOOL CmdOnEvent(struct IOSana2Req *request,struct DevBase *base);
  66. static BOOL CmdReadOrphan(struct IOSana2Req *request,
  67.    struct DevBase *base);
  68. static BOOL CmdOnline(struct IOSana2Req *request,struct DevBase *base);
  69. static BOOL CmdOffline(struct IOSana2Req *request,struct DevBase *base);
  70. static BOOL CmdDeviceQuery(struct IOStdReq *request,
  71.    struct DevBase *base);
  72. static BOOL CmdAddMulticastAddresses(struct IOSana2Req *request,
  73.    struct DevBase *base);
  74. static BOOL CmdDelMulticastAddresses(struct IOSana2Req *request,
  75.    struct DevBase *base);
  76.  
  77.  
  78. static const UWORD supported_commands[]=
  79. {
  80.    CMD_READ,
  81.    CMD_WRITE,
  82.    CMD_FLUSH,
  83.    S2_DEVICEQUERY,
  84.    S2_GETSTATIONADDRESS,
  85.    S2_CONFIGINTERFACE,
  86.    S2_ADDMULTICASTADDRESS,
  87.    S2_DELMULTICASTADDRESS,
  88.    S2_MULTICAST,
  89.    S2_BROADCAST,
  90.    S2_TRACKTYPE,
  91.    S2_UNTRACKTYPE,
  92.    S2_GETTYPESTATS,
  93.    S2_GETSPECIALSTATS,
  94.    S2_GETGLOBALSTATS,
  95.    S2_ONEVENT,
  96.    S2_READORPHAN,
  97.    S2_ONLINE,
  98.    S2_OFFLINE,
  99.    NSCMD_DEVICEQUERY,
  100. /*   S2_3C589_WRITEEEPROM,*/
  101.    S2_ADDMULTICASTADDRESSES,
  102.    S2_DELMULTICASTADDRESSES,
  103.    0
  104. };
  105.  
  106.  
  107. struct Sana2DeviceQuery sana2_info=
  108. {
  109.    0,
  110.    0,
  111.    0,
  112.    0,
  113.    ADDRESS_SIZE*8,
  114.    MTU,
  115.    10000000,
  116.    S2WireType_Ethernet
  117. };
  118.  
  119.  
  120.  
  121. /****i* 3c589.device/ServiceRequest ****************************************
  122. *
  123. *   NAME
  124. *    ServiceRequest -- Attempt to service a device request.
  125. *
  126. *   SYNOPSIS
  127. *    ServiceRequest(request)
  128. *
  129. *    VOID ServiceRequest(struct IORequest *);
  130. *
  131. *   FUNCTION
  132. *    Attempts to carry out a request. The relevant unit's semaphore must
  133. *    be obtained before calling this function. This function releases the
  134. *    semaphore before returning.
  135. *
  136. *   INPUTS
  137. *    request
  138. *
  139. *   RESULT
  140. *    None.
  141. *
  142. *   EXAMPLE
  143. *
  144. *   NOTES
  145. *
  146. *   BUGS
  147. *
  148. *   SEE ALSO
  149. *
  150. ****************************************************************************
  151. *
  152. */
  153.  
  154. VOID ServiceRequest(struct IOSana2Req *request,struct DevBase *base)
  155. {
  156.    BOOL complete;
  157.  
  158.    switch(request->ios2_Req.io_Command)
  159.    {
  160.    case CMD_READ:
  161.       complete=CmdRead(request,base);
  162.       break;
  163.    case CMD_WRITE:
  164.       complete=CmdWrite(request,base);
  165.       break;
  166.    case CMD_FLUSH:
  167.       complete=CmdFlush((APTR)request,base);
  168.       break;
  169.    case S2_DEVICEQUERY:
  170.       complete=CmdS2DeviceQuery((APTR)request,base);
  171.       break;
  172.    case S2_GETSTATIONADDRESS:
  173.       complete=CmdGetStationAddress((APTR)request,base);
  174.       break;
  175.    case S2_CONFIGINTERFACE:
  176.       complete=CmdConfigInterface((APTR)request,base);
  177.       break;
  178.    case S2_ADDMULTICASTADDRESS:
  179.       complete=CmdAddMulticastAddresses((APTR)request,base);
  180.       break;
  181.    case S2_DELMULTICASTADDRESS:
  182.       complete=CmdDelMulticastAddresses((APTR)request,base);
  183.       break;
  184.    case S2_MULTICAST:
  185.       complete=CmdWrite((APTR)request,base);
  186.       break;
  187.    case S2_BROADCAST:
  188.       complete=CmdBroadcast((APTR)request,base);
  189.       break;
  190.    case S2_TRACKTYPE:
  191.       complete=CmdTrackType((APTR)request,base);
  192.       break;
  193.    case S2_UNTRACKTYPE:
  194.       complete=CmdUntrackType((APTR)request,base);
  195.       break;
  196.    case S2_GETTYPESTATS:
  197.       complete=CmdGetTypeStats((APTR)request,base);
  198.       break;
  199.    case S2_GETSPECIALSTATS:
  200.       complete=CmdGetSpecialStats((APTR)request,base);
  201.       break;
  202.    case S2_GETGLOBALSTATS:
  203.       complete=CmdGetGlobalStats((APTR)request,base);
  204.       break;
  205.    case S2_ONEVENT:
  206.       complete=CmdOnEvent((APTR)request,base);
  207.       break;
  208.    case S2_READORPHAN:
  209.       complete=CmdReadOrphan((APTR)request,base);
  210.       break;
  211.    case S2_ONLINE:
  212.       complete=CmdOnline((APTR)request,base);
  213.       break;
  214.    case S2_OFFLINE:
  215.       complete=CmdOffline((APTR)request,base);
  216.       break;
  217.    case NSCMD_DEVICEQUERY:
  218.       complete=CmdDeviceQuery((APTR)request,base);
  219.       break;
  220.    case S2_ADDMULTICASTADDRESSES:
  221.       complete=CmdAddMulticastAddresses((APTR)request,base);
  222.       break;
  223.    case S2_DELMULTICASTADDRESSES:
  224.       complete=CmdDelMulticastAddresses((APTR)request,base);
  225.       break;
  226.    default:
  227.       complete=CmdInvalid((APTR)request,base);
  228.    }
  229.  
  230.    if(complete&&((request->ios2_Req.io_Flags&IOF_QUICK)==0))
  231.       ReplyMsg((APTR)request);
  232.  
  233.    ReleaseSemaphore(&((struct DevUnit *)request->ios2_Req.io_Unit)->
  234.       access_lock);
  235.    return;
  236. }
  237.  
  238.  
  239.  
  240. /****i* 3c589.device/CMD_INVALID *******************************************
  241. *
  242. *   NAME
  243. *    CMD_INVALID -- Reject invalid commands.
  244. *
  245. *   FUNCTION
  246. *
  247. *   INPUTS
  248. *    None.
  249. *
  250. *   RESULTS
  251. *    io_Error - IOERR_NOCMD.
  252. *
  253. *   EXAMPLE
  254. *
  255. *   NOTES
  256. *
  257. *   BUGS
  258. *
  259. *   SEE ALSO
  260. *
  261. ****************************************************************************
  262. *
  263. */
  264.  
  265. static BOOL CmdInvalid(struct IOSana2Req *request,struct DevBase *base)
  266. {
  267.    request->ios2_Req.io_Error=IOERR_NOCMD;
  268.  
  269.    return TRUE;
  270. }
  271.  
  272.  
  273.  
  274. /****** 3c589.device/CMD_READ **********************************************
  275. *
  276. *   NAME
  277. *    CMD_READ -- Read data.
  278. *
  279. *   FUNCTION
  280. *
  281. *   INPUTS
  282. *    io_Flags
  283. *    ios2_PacketType
  284. *    ios2_Data
  285. *
  286. *   RESULTS
  287. *    io_Flags
  288. *    io_Error
  289. *    ios2_WireError
  290. *    ios2_SrcAddr
  291. *    ios2_DstAddr
  292. *    ios2_DataLength
  293. *    ios2_Data
  294. *
  295. *   EXAMPLE
  296. *
  297. *   NOTES
  298. *
  299. *   BUGS
  300. *
  301. *   SEE ALSO
  302. *
  303. ****************************************************************************
  304. *
  305. */
  306.  
  307. static BOOL CmdRead(struct IOSana2Req *request,struct DevBase *base)
  308. {
  309.    struct DevUnit *unit;
  310.    struct Opener *opener;
  311.    BOOL complete=FALSE;
  312.  
  313.    unit=(APTR)request->ios2_Req.io_Unit;
  314.  
  315.    if((unit->flags&UNITF_ONLINE)!=0)
  316.    {
  317.       opener=request->ios2_BufferManagement;
  318.       PutRequest(&opener->read_port,(APTR)request,base);
  319.    }
  320.    else
  321.    {
  322.       request->ios2_Req.io_Error=S2ERR_OUTOFSERVICE;
  323.       request->ios2_WireError=S2WERR_UNIT_OFFLINE;
  324.       complete=TRUE;
  325.    }
  326.  
  327.    /* Return */
  328.  
  329.    return complete;
  330. }
  331.  
  332.  
  333.  
  334. /****** 3c589.device/CMD_WRITE *********************************************
  335. *
  336. *   NAME
  337. *    CMD_WRITE -- Write data.
  338. *
  339. *   FUNCTION
  340. *
  341. *   INPUTS
  342. *    io_Flags
  343. *    ios2_DstAddr
  344. *    ios2_PacketType
  345. *    ios2_DataLength
  346. *    ios2_Data
  347. *
  348. *   RESULTS
  349. *    io_Error
  350. *    ios2_WireError
  351. *
  352. *   EXAMPLE
  353. *
  354. *   NOTES
  355. *
  356. *   BUGS
  357. *
  358. *   SEE ALSO
  359. *
  360. ****************************************************************************
  361. *
  362. */
  363.  
  364. /****** 3c589.device/S2_MULTICAST ******************************************
  365. *
  366. *   NAME
  367. *    S2_MULTICAST --
  368. *
  369. *   FUNCTION
  370. *
  371. *   INPUTS
  372. *    io_Flags
  373. *    ios2_DstAddr - multicast address.
  374. *    ios2_PacketType
  375. *    ios2_DataLength
  376. *    ios2_Data
  377. *
  378. *   RESULTS
  379. *    io_Error
  380. *    ios2_WireError
  381. *
  382. *   EXAMPLE
  383. *
  384. *   NOTES
  385. *
  386. *   BUGS
  387. *
  388. *   SEE ALSO
  389. *
  390. ****************************************************************************
  391. *
  392. */
  393.  
  394. static BOOL CmdWrite(struct IOSana2Req *request,struct DevBase *base)
  395. {
  396.    struct DevUnit *unit;
  397.    BYTE error=0;
  398.    ULONG wire_error;
  399.    BOOL complete=FALSE;
  400.  
  401.    /* Check request is valid */
  402.  
  403.    unit=(APTR)request->ios2_Req.io_Unit;
  404.    if((unit->flags&UNITF_ONLINE)==0)
  405.    {
  406.       error=S2ERR_OUTOFSERVICE;
  407.       wire_error=S2WERR_UNIT_OFFLINE;
  408.    }
  409.    else if((request->ios2_Req.io_Command==S2_MULTICAST)&&
  410.       ((request->ios2_DstAddr[0]&0x1)==0))
  411.    {
  412.       error=S2ERR_BAD_ADDRESS;
  413.       wire_error=S2WERR_BAD_MULTICAST;
  414.    }
  415.  
  416.    /* Queue request for sending */
  417.  
  418.    if(error==0)
  419.       PutRequest(unit->request_ports[WRITE_QUEUE],(APTR)request,base);
  420.    else
  421.    {
  422.       request->ios2_Req.io_Error=error;
  423.       request->ios2_WireError=wire_error;
  424.       complete=TRUE;
  425.    }
  426.  
  427.    /* Return */
  428.  
  429.    return complete;
  430. }
  431.  
  432.  
  433.  
  434. /****** 3c589.device/CMD_FLUSH *********************************************
  435. *
  436. *   NAME
  437. *    CMD_FLUSH -- .
  438. *
  439. *   FUNCTION
  440. *
  441. *   INPUTS
  442. *    None.
  443. *
  444. *   RESULTS
  445. *    io_Error
  446. *
  447. *   EXAMPLE
  448. *
  449. *   NOTES
  450. *
  451. *   BUGS
  452. *
  453. *   SEE ALSO
  454. *
  455. ****************************************************************************
  456. *
  457. */
  458.  
  459. static BOOL CmdFlush(struct IORequest *request,struct DevBase *base)
  460. {
  461.    FlushUnit((APTR)request->io_Unit,EVENT_QUEUE,IOERR_ABORTED,base);
  462.  
  463.    return TRUE;
  464. }
  465.  
  466.  
  467.  
  468. /****** 3c589.device/S2_DEVICEQUERY ****************************************
  469. *
  470. *   NAME
  471. *    S2_DEVICEQUERY -- Query device capabilities.
  472. *
  473. *   FUNCTION
  474. *
  475. *   INPUTS
  476. *    ios2_StatData - Pointer to Sana2DeviceQuery structure.
  477. *
  478. *   RESULTS
  479. *    io_Error
  480. *    ios2_WireError
  481. *
  482. *   EXAMPLE
  483. *
  484. *   NOTES
  485. *
  486. *   BUGS
  487. *
  488. *   SEE ALSO
  489. *
  490. ****************************************************************************
  491. *
  492. */
  493.  
  494. static BOOL CmdS2DeviceQuery(struct IOSana2Req *request,
  495.    struct DevBase *base)
  496. {
  497.    struct Sana2DeviceQuery *info;
  498.    ULONG size_available,size;
  499.  
  500.    /* Copy device info */
  501.  
  502.    info=request->ios2_StatData;
  503.    size=size_available=info->SizeAvailable;
  504.    if(size>sizeof(struct Sana2DeviceQuery))
  505.       size=sizeof(struct Sana2DeviceQuery);
  506.  
  507.    CopyMem(&sana2_info,info,size);
  508.  
  509.    info->SizeAvailable=size_available;
  510.    info->SizeSupplied=size;
  511.  
  512.    /* Return */
  513.  
  514.    return TRUE;
  515. }
  516.  
  517.  
  518.  
  519. /****** 3c589.device/S2_GETSTATIONADDDRESS *********************************
  520. *
  521. *   NAME
  522. *    S2_GETSTATIONADDDRESS --
  523. *
  524. *   FUNCTION
  525. *
  526. *   INPUTS
  527. *    None.
  528. *
  529. *   RESULTS
  530. *    io_Error
  531. *    ios2_WireError
  532. *    ios2_SrcAddr - current address.
  533. *    ios2_DstAddr - default address (zero if none?).
  534. *
  535. *   EXAMPLE
  536. *
  537. *   NOTES
  538. *
  539. *   BUGS
  540. *
  541. *   SEE ALSO
  542. *
  543. ****************************************************************************
  544. *
  545. */
  546.  
  547. static BOOL CmdGetStationAddress(struct IOSana2Req *request,
  548.    struct DevBase *base)
  549. {
  550.    struct DevUnit *unit;
  551.  
  552.    /* Copy addresses */
  553.  
  554.    unit=(APTR)request->ios2_Req.io_Unit;
  555.    CopyMem(unit->address,request->ios2_SrcAddr,ADDRESS_SIZE);
  556.    CopyMem(unit->default_address,request->ios2_DstAddr,ADDRESS_SIZE);
  557.  
  558.    /* Return */
  559.  
  560.    return TRUE;
  561. }
  562.  
  563.  
  564.  
  565. /****** 3c589.device/S2_CONFIGINTERFACE ************************************
  566. *
  567. *   NAME
  568. *    S2_CONFIGINTERFACE --
  569. *
  570. *   FUNCTION
  571. *
  572. *   INPUTS
  573. *    ios2_SrcAddr - address to use.
  574. *
  575. *   RESULTS
  576. *    io_Error
  577. *    ios2_WireError
  578. *    ios2_SrcAddr - address used.
  579. *
  580. *   EXAMPLE
  581. *
  582. *   NOTES
  583. *
  584. *   BUGS
  585. *
  586. *   SEE ALSO
  587. *
  588. ****************************************************************************
  589. *
  590. */
  591.  
  592. static BOOL CmdConfigInterface(struct IOSana2Req *request,
  593.    struct DevBase *base)
  594. {
  595.    struct DevUnit *unit;
  596.  
  597.    /* Configure adapter */
  598.  
  599.    unit=(APTR)request->ios2_Req.io_Unit;
  600.    if((unit->flags&UNITF_CONFIGURED)==0)
  601.    {
  602.       CopyMem(request->ios2_SrcAddr,unit->address,ADDRESS_SIZE);
  603.       if((unit->flags&UNITF_HAVEADAPTER)!=0)
  604.          ConfigureAdapter(unit,base);
  605.       unit->flags|=UNITF_CONFIGURED;
  606.    }
  607.    else
  608.    {
  609.       request->ios2_Req.io_Error=S2ERR_BAD_STATE;
  610.       request->ios2_WireError=S2WERR_IS_CONFIGURED;
  611.    }
  612.  
  613.    /* Return */
  614.  
  615.    return TRUE;
  616. }
  617.  
  618.  
  619.  
  620. /****** 3c589.device/S2_BROADCAST ******************************************
  621. *
  622. *   NAME
  623. *    S2_BROADCAST --
  624. *
  625. *   FUNCTION
  626. *
  627. *   INPUTS
  628. *    io_Flags
  629. *    ios2_PacketType
  630. *    ios2_DataLength
  631. *    ios2_Data
  632. *
  633. *   RESULTS
  634. *    io_Error
  635. *    ios2_WireError
  636. *
  637. *   EXAMPLE
  638. *
  639. *   NOTES
  640. *
  641. *   BUGS
  642. *
  643. *   SEE ALSO
  644. *
  645. ****************************************************************************
  646. *
  647. */
  648.  
  649. static BOOL CmdBroadcast(struct IOSana2Req *request,
  650.    struct DevBase *base)
  651. {
  652.    /* Fill in the broadcast address as destination */
  653.  
  654.    *((ULONG *)request->ios2_DstAddr)=0xffffffff;
  655.    *((UWORD *)(request->ios2_DstAddr+4))=0xffff;
  656.  
  657.    /* Queue the write as normal */
  658.  
  659.    return CmdWrite(request,base);
  660. }
  661.  
  662.  
  663.  
  664. /****** 3c589.device/S2_TRACKTYPE ******************************************
  665. *
  666. *   NAME
  667. *    S2_TRACKTYPE --
  668. *
  669. *   FUNCTION
  670. *
  671. *   INPUTS
  672. *    ios2_PacketType - packet type to start tracking.
  673. *
  674. *   RESULTS
  675. *    io_Error
  676. *    ios2_WireError
  677. *
  678. *   EXAMPLE
  679. *
  680. *   NOTES
  681. *
  682. *   BUGS
  683. *
  684. *   SEE ALSO
  685. *
  686. ****************************************************************************
  687. *
  688. */
  689.  
  690. static BOOL CmdTrackType(struct IOSana2Req *request,
  691.    struct DevBase *base)
  692. {
  693.    struct DevUnit *unit;
  694.    struct Opener *opener;
  695.    ULONG packet_type,wire_error;
  696.    struct TypeTracker *tracker;
  697.    struct TypeStats *initial_stats;
  698.    BYTE error=0;
  699.  
  700.    unit=(APTR)request->ios2_Req.io_Unit;
  701.    packet_type=request->ios2_PacketType;
  702.  
  703.    /* Get global tracker */
  704.  
  705.    tracker=(struct TypeTracker *)
  706.       FindTypeStats(unit,&unit->type_trackers,packet_type,base);
  707.  
  708.    if(tracker!=NULL)
  709.       tracker->user_count++;
  710.    else
  711.    {
  712.       tracker=AllocMem(sizeof(struct TypeTracker),MEMF_PUBLIC|MEMF_CLEAR);
  713.       if(tracker!=NULL)
  714.       {
  715.          tracker->packet_type=packet_type;
  716.          tracker->user_count=1;
  717.  
  718.          Disable();
  719.          AddTail((APTR)&unit->type_trackers,(APTR)tracker);
  720.          Enable();
  721.       }
  722.    }
  723.  
  724.    /* Store initial figures for this opener */
  725.  
  726.    opener=request->ios2_BufferManagement;
  727.    initial_stats=FindTypeStats(unit,&opener->initial_stats,packet_type,
  728.       base);
  729.  
  730.    if(initial_stats!=NULL)
  731.    {
  732.       error=S2ERR_BAD_STATE;
  733.       wire_error=S2WERR_ALREADY_TRACKED;
  734.    }
  735.  
  736.    if(error==0)
  737.    {
  738.       initial_stats=AllocMem(sizeof(struct TypeStats),MEMF_PUBLIC);
  739.       if(initial_stats==NULL)
  740.       {
  741.          error=S2ERR_NO_RESOURCES;
  742.          wire_error=S2WERR_GENERIC_ERROR;
  743.       }
  744.    }
  745.  
  746.    if(error==0)
  747.    {
  748.       CopyMem(tracker,initial_stats,sizeof(struct TypeStats));
  749.       AddTail((APTR)&opener->initial_stats,(APTR)initial_stats);
  750.    }
  751.  
  752.    /* Return */
  753.  
  754.    request->ios2_Req.io_Error=error;
  755.    request->ios2_WireError=wire_error;
  756.    return TRUE;
  757. }
  758.  
  759.  
  760.  
  761. /****** 3c589.device/S2_UNTRACKTYPE ****************************************
  762. *
  763. *   NAME
  764. *    S2_UNTRACKTYPE --
  765. *
  766. *   FUNCTION
  767. *
  768. *   INPUTS
  769. *    ios2_PacketType - packet type to stop tracking.
  770. *
  771. *   RESULTS
  772. *    io_Error
  773. *    ios2_WireError
  774. *
  775. *   EXAMPLE
  776. *
  777. *   NOTES
  778. *
  779. *   BUGS
  780. *
  781. *   SEE ALSO
  782. *
  783. ****************************************************************************
  784. *
  785. */
  786.  
  787. static BOOL CmdUntrackType(struct IOSana2Req *request,
  788.    struct DevBase *base)
  789. {
  790.    struct DevUnit *unit;
  791.    struct Opener *opener;
  792.    ULONG packet_type;
  793.    struct TypeTracker *tracker;
  794.    struct TypeStats *initial_stats;
  795.  
  796.    unit=(APTR)request->ios2_Req.io_Unit;
  797.    packet_type=request->ios2_PacketType;
  798.  
  799.    /* Get global tracker and initial figures */
  800.  
  801.    tracker=(struct TypeTracker *)
  802.       FindTypeStats(unit,&unit->type_trackers,packet_type,base);
  803.    opener=request->ios2_BufferManagement;
  804.    initial_stats=FindTypeStats(unit,&opener->initial_stats,packet_type,
  805.       base);
  806.  
  807.    /* Decrement tracker usage and free unused structures */
  808.  
  809.    if(initial_stats!=NULL)
  810.    {
  811.       if((--tracker->user_count)==0)
  812.       {
  813.          Disable();
  814.          Remove((APTR)tracker);
  815.          Enable();
  816.          FreeMem(tracker,sizeof(struct TypeTracker));
  817.       }
  818.  
  819.       Remove((APTR)initial_stats);
  820.       FreeMem(initial_stats,sizeof(struct TypeStats));
  821.    }
  822.    else
  823.    {
  824.       request->ios2_Req.io_Error=S2ERR_BAD_STATE;
  825.       request->ios2_WireError=S2WERR_NOT_TRACKED;
  826.    }
  827.  
  828.    /* Return */
  829.  
  830.    return TRUE;
  831. }
  832.  
  833.  
  834.  
  835. /****** 3c589.device/S2_GETTYPESTATS ***************************************
  836. *
  837. *   NAME
  838. *    S2_GETTYPESTATS --
  839. *
  840. *   FUNCTION
  841. *
  842. *   INPUTS
  843. *    ios2_PacketType - packet type to get statistics on.
  844. *    ios2_StatData - pointer to a Sana2PacketTypeStats structure.
  845. *
  846. *   RESULTS
  847. *    io_Error
  848. *    ios2_WireError
  849. *
  850. *   EXAMPLE
  851. *
  852. *   NOTES
  853. *
  854. *   BUGS
  855. *
  856. *   SEE ALSO
  857. *
  858. ****************************************************************************
  859. *
  860. */
  861.  
  862. static BOOL CmdGetTypeStats(struct IOSana2Req *request,
  863.    struct DevBase *base)
  864. {
  865.    struct DevUnit *unit;
  866.    struct Opener *opener;
  867.    ULONG packet_type;
  868.    struct TypeStats *initial_stats,*tracker;
  869.    struct Sana2PacketTypeStats *stats;
  870.  
  871.    unit=(APTR)request->ios2_Req.io_Unit;
  872.    packet_type=request->ios2_PacketType;
  873.  
  874.    /* Get global tracker and initial figures */
  875.  
  876.    tracker=FindTypeStats(unit,&unit->type_trackers,packet_type,base);
  877.    opener=request->ios2_BufferManagement;
  878.    initial_stats=FindTypeStats(unit,&opener->initial_stats,packet_type,
  879.       base);
  880.  
  881.    /* Copy and adjust figures */
  882.  
  883.    if(initial_stats!=NULL)
  884.    {
  885.       stats=request->ios2_StatData;
  886.       CopyMem(&tracker->stats,stats,sizeof(struct Sana2PacketTypeStats));
  887.       stats->PacketsSent-=initial_stats->stats.PacketsSent;
  888.       stats->PacketsReceived-=initial_stats->stats.PacketsReceived;
  889.       stats->BytesSent-=initial_stats->stats.BytesSent;
  890.       stats->BytesReceived-=initial_stats->stats.BytesReceived;
  891.       stats->PacketsDropped-=initial_stats->stats.PacketsDropped;
  892.    }
  893.    else
  894.    {
  895.       request->ios2_Req.io_Error=S2ERR_BAD_STATE;
  896.       request->ios2_WireError=S2WERR_NOT_TRACKED;
  897.    }
  898.  
  899.    /* Return */
  900.  
  901.    return TRUE;
  902. }
  903.  
  904.  
  905.  
  906. /****** 3c589.device/S2_GETSPECIALSTATS ************************************
  907. *
  908. *   NAME
  909. *    S2_GETSPECIALSTATS --
  910. *
  911. *   FUNCTION
  912. *
  913. *   INPUTS
  914. *    ios2_StatData - Pointer to Sana2SpecialStatHeader structure.
  915. *
  916. *   RESULTS
  917. *    io_Error
  918. *    ios2_WireError
  919. *
  920. *   EXAMPLE
  921. *
  922. *   NOTES
  923. *
  924. *   BUGS
  925. *
  926. *   SEE ALSO
  927. *
  928. ****************************************************************************
  929. *
  930. */
  931.  
  932. static BOOL CmdGetSpecialStats(struct IOSana2Req *request,
  933.    struct DevBase *base)
  934. {
  935.    struct DevUnit *unit;
  936.    UWORD i,stat_count;
  937.    struct Sana2SpecialStatHeader *header;
  938.    struct Sana2SpecialStatRecord *record;
  939.  
  940.    /* Fill in stats */
  941.  
  942.    unit=(APTR)request->ios2_Req.io_Unit;
  943.    header=request->ios2_StatData;
  944.    record=(APTR)(header+1);
  945.  
  946.    stat_count=header->RecordCountMax;
  947.    if(stat_count>STAT_COUNT)
  948.       stat_count=STAT_COUNT;
  949.  
  950.    for(i=0;i<stat_count;i++)
  951.    {
  952.       record->Type=(S2WireType_Ethernet<<16)+i;
  953.       record->Count=unit->special_stats[i];
  954.       record->String=(TEXT *)&unit->openers.mlh_Tail;
  955.       record++;
  956.    }
  957.  
  958.    header->RecordCountSupplied=stat_count;
  959.  
  960.    /* Return */
  961.  
  962.    return TRUE;
  963. }
  964.  
  965.  
  966.  
  967. /****** 3c589.device/S2_GETGLOBALSTATS *************************************
  968. *
  969. *   NAME
  970. *    S2_GETGLOBALSTATS --
  971. *
  972. *   FUNCTION
  973. *
  974. *   INPUTS
  975. *    ios2_StatData - Pointer to Sana2DeviceStats structure.
  976. *
  977. *   RESULTS
  978. *    io_Error
  979. *    ios2_WireError
  980. *
  981. *   EXAMPLE
  982. *
  983. *   NOTES
  984. *
  985. *   BUGS
  986. *
  987. *   SEE ALSO
  988. *
  989. ****************************************************************************
  990. *
  991. */
  992.  
  993. static BOOL CmdGetGlobalStats(struct IOSana2Req *request,
  994.    struct DevBase *base)
  995. {
  996.    struct DevUnit *unit;
  997.  
  998.    /* Copy stats */
  999.  
  1000.    unit=(APTR)request->ios2_Req.io_Unit;
  1001.    CopyMem(&unit->stats,request->ios2_StatData,
  1002.       sizeof(struct Sana2DeviceStats));
  1003.  
  1004.    /* Return */
  1005.  
  1006.    return TRUE;
  1007. }
  1008.  
  1009.  
  1010.  
  1011. /****** 3c589.device/S2_ONEVENT ********************************************
  1012. *
  1013. *   NAME
  1014. *    S2_ONEVENT --
  1015. *
  1016. *   FUNCTION
  1017. *
  1018. *   INPUTS
  1019. *    ios2_WireError
  1020. *
  1021. *   RESULTS
  1022. *    io_Error
  1023. *    ios2_WireError
  1024. *
  1025. *   EXAMPLE
  1026. *
  1027. *   NOTES
  1028. *
  1029. *   BUGS
  1030. *
  1031. *   SEE ALSO
  1032. *
  1033. ****************************************************************************
  1034. *
  1035. */
  1036.  
  1037. static BOOL CmdOnEvent(struct IOSana2Req *request,struct DevBase *base)
  1038. {
  1039.    struct DevUnit *unit;
  1040.    ULONG events,wanted_events;
  1041.    BOOL complete=FALSE;
  1042.  
  1043.    /* Check if we understand the event types */
  1044.  
  1045.    unit=(APTR)request->ios2_Req.io_Unit;
  1046.    wanted_events=request->ios2_WireError;
  1047.    if((wanted_events&~KNOWN_EVENTS)!=0)
  1048.    {
  1049.       request->ios2_Req.io_Error=S2ERR_NOT_SUPPORTED;
  1050.       events=S2WERR_BAD_EVENT;
  1051.    }
  1052.    else
  1053.    {
  1054.       if((unit->flags&UNITF_ONLINE)!=0)
  1055.          events=S2EVENT_ONLINE;
  1056.       else
  1057.          events=S2EVENT_OFFLINE;
  1058.  
  1059.       events&=wanted_events;
  1060.    }
  1061.  
  1062.    /* Reply request if a wanted event has already occurred */
  1063.  
  1064.    if(events!=0)
  1065.    {
  1066.       request->ios2_WireError=events;
  1067.       complete=TRUE;
  1068.    }
  1069.    else
  1070.       PutRequest(unit->request_ports[EVENT_QUEUE],(APTR)request,base);
  1071.  
  1072.    /* Return */
  1073.  
  1074.    return complete;
  1075. }
  1076.  
  1077.  
  1078.  
  1079. /****** 3c589.device/S2_READORPHAN *****************************************
  1080. *
  1081. *   NAME
  1082. *    S2_READORPHAN --
  1083. *
  1084. *   FUNCTION
  1085. *
  1086. *   INPUTS
  1087. *    io_Flags
  1088. *    ios2_Data
  1089. *
  1090. *   RESULTS
  1091. *    io_Flags
  1092. *    io_Error
  1093. *    ios2_WireError
  1094. *    ios2_PacketType - A copy of the packet's type field.
  1095. *    ios2_SrcAddr
  1096. *    ios2_DstAddr
  1097. *    ios2_DataLength
  1098. *    ios2_Data
  1099. *
  1100. *
  1101. *   EXAMPLE
  1102. *
  1103. *   NOTES
  1104. *
  1105. *   BUGS
  1106. *
  1107. *   SEE ALSO
  1108. *
  1109. ****************************************************************************
  1110. *
  1111. */
  1112.  
  1113. static BOOL CmdReadOrphan(struct IOSana2Req *request,
  1114.    struct DevBase *base)
  1115. {
  1116.    struct DevUnit *unit;
  1117.    BYTE error=0;
  1118.    ULONG wire_error;
  1119.    BOOL complete=FALSE;
  1120.  
  1121.    /* Check request is valid */
  1122.  
  1123.    unit=(APTR)request->ios2_Req.io_Unit;
  1124.    if((unit->flags&UNITF_ONLINE)==0)
  1125.    {
  1126.       error=S2ERR_OUTOFSERVICE;
  1127.       wire_error=S2WERR_UNIT_OFFLINE;
  1128.    }
  1129.  
  1130.    /* Queue request */
  1131.  
  1132.    if(error==0)
  1133.       PutRequest(unit->request_ports[ADOPT_QUEUE],(APTR)request,base);
  1134.    else
  1135.    {
  1136.       request->ios2_Req.io_Error=error;
  1137.       request->ios2_WireError=wire_error;
  1138.       complete=TRUE;
  1139.    }
  1140.  
  1141.    /* Return */
  1142.  
  1143.    return complete;
  1144. }
  1145.  
  1146.  
  1147.  
  1148. /****** 3c589.device/S2_ONLINE *********************************************
  1149. *
  1150. *   NAME
  1151. *    S2_ONLINE --
  1152. *
  1153. *   FUNCTION
  1154. *
  1155. *   INPUTS
  1156. *    None.
  1157. *
  1158. *   RESULTS
  1159. *    io_Error
  1160. *    ios2_WireError
  1161. *
  1162. *   EXAMPLE
  1163. *
  1164. *   NOTES
  1165. *
  1166. *   BUGS
  1167. *
  1168. *   SEE ALSO
  1169. *
  1170. ****************************************************************************
  1171. *
  1172. */
  1173.  
  1174. static BOOL CmdOnline(struct IOSana2Req *request,struct DevBase *base)
  1175. {
  1176.    struct DevUnit *unit;
  1177.    BYTE error=0;
  1178.    ULONG wire_error;
  1179.    UWORD i;
  1180.  
  1181.    /* Check request is valid */
  1182.  
  1183.    unit=(APTR)request->ios2_Req.io_Unit;
  1184.    if((unit->flags&UNITF_CONFIGURED)==0)
  1185.    {
  1186.       error=S2ERR_BAD_STATE;
  1187.       wire_error=S2WERR_NOT_CONFIGURED;
  1188.    }
  1189.    if((unit->flags&UNITF_HAVEADAPTER)==0)
  1190.    {
  1191.       error=S2ERR_OUTOFSERVICE;
  1192.       wire_error=S2WERR_RCVREL_HDW_ERR;
  1193.    }
  1194.  
  1195.    /* Clear global and special stats and put adapter back online */
  1196.  
  1197.    if((error==0)&&((unit->flags&UNITF_ONLINE)==0))
  1198.    {
  1199.       unit->stats.PacketsReceived=0;
  1200.       unit->stats.PacketsSent=0;
  1201.       unit->stats.BadData=0;
  1202.       unit->stats.Overruns=0;
  1203.       unit->stats.UnknownTypesReceived=0;
  1204.       unit->stats.Reconfigurations=0;
  1205.  
  1206.       for(i=0;i<STAT_COUNT;i++)
  1207.          unit->special_stats[i]=0;
  1208.  
  1209.       GoOnline(unit,base);
  1210.    }
  1211.  
  1212.    /* Return */
  1213.  
  1214.    request->ios2_Req.io_Error=error;
  1215.    request->ios2_WireError=wire_error;
  1216.    return TRUE;
  1217. }
  1218.  
  1219.  
  1220.  
  1221. /****** 3c589.device/S2_OFFLINE ********************************************
  1222. *
  1223. *   NAME
  1224. *    S2_OFFLINE --
  1225. *
  1226. *   FUNCTION
  1227. *
  1228. *   INPUTS
  1229. *    None.
  1230. *
  1231. *   RESULTS
  1232. *    io_Error
  1233. *    ios2_WireError
  1234. *
  1235. *   EXAMPLE
  1236. *
  1237. *   NOTES
  1238. *
  1239. *   BUGS
  1240. *
  1241. *   SEE ALSO
  1242. *
  1243. ****************************************************************************
  1244. *
  1245. */
  1246.  
  1247. static BOOL CmdOffline(struct IOSana2Req *request,struct DevBase *base)
  1248. {
  1249.    struct DevUnit *unit;
  1250.  
  1251.    /* Put adapter offline */
  1252.  
  1253.    unit=(APTR)request->ios2_Req.io_Unit;
  1254.    if((unit->flags&UNITF_ONLINE)!=0)
  1255.       GoOffline(unit,base);
  1256.  
  1257.    /* Return */
  1258.  
  1259.    return TRUE;
  1260. }
  1261.  
  1262.  
  1263.  
  1264. /****** 3c589.device/NSCMD_DEVICEQUERY *************************************
  1265. *
  1266. *   NAME
  1267. *    NSCMD_DEVICEQUERY -- Query device capabilities.
  1268. *
  1269. *   FUNCTION
  1270. *
  1271. *   INPUTS
  1272. *    io_Length - ???.
  1273. *    io_Data - Pointer to NSDeviceQueryResult structure.
  1274. *
  1275. *   RESULTS
  1276. *    io_Error
  1277. *    io_Actual - size of structure device can handle.
  1278. *
  1279. *   EXAMPLE
  1280. *
  1281. *   NOTES
  1282. *
  1283. *   BUGS
  1284. *
  1285. *   SEE ALSO
  1286. *
  1287. ****************************************************************************
  1288. *
  1289. * Note that we have to pretend the request structure is an IOStdReq.
  1290. *
  1291. */
  1292.  
  1293. static BOOL CmdDeviceQuery(struct IOStdReq *request,
  1294.    struct DevBase *base)
  1295. {
  1296.    struct NSDeviceQueryResult *info;
  1297.  
  1298.    /* Set structure size twice */
  1299.  
  1300.    info=request->io_Data;
  1301.    request->io_Actual=info->SizeAvailable=
  1302.       OFFSET(NSDeviceQueryResult,SupportedCommands)+sizeof(APTR);
  1303.  
  1304.    /* Report device details */
  1305.  
  1306.    info->DeviceType=NSDEVTYPE_SANA2;
  1307.    info->DeviceSubType=0;
  1308.  
  1309.    info->SupportedCommands=(APTR)supported_commands;
  1310.  
  1311.    /* Return */
  1312.  
  1313.    return TRUE;
  1314. }
  1315.  
  1316.  
  1317.  
  1318. /****** 3c589.device/S2_ADDMULTICASTADDRESS ********************************
  1319. *
  1320. *   NAME
  1321. *    S2_ADDMULTICASTADDRESS --
  1322. *
  1323. *   FUNCTION
  1324. *
  1325. *   INPUTS
  1326. *    ios2_SrcAddr - multicast address.
  1327. *
  1328. *   RESULTS
  1329. *    io_Error
  1330. *    ios2_WireError
  1331. *
  1332. *   EXAMPLE
  1333. *
  1334. *   NOTES
  1335. *
  1336. *   BUGS
  1337. *
  1338. *   SEE ALSO
  1339. *
  1340. ****************************************************************************
  1341. *
  1342. */
  1343.  
  1344. /****** 3c589.device/S2_ADDMULTICASTADDRESSES ******************************
  1345. *
  1346. *   NAME
  1347. *    S2_ADDMULTICASTADDRESSES --
  1348. *
  1349. *   FUNCTION
  1350. *
  1351. *   INPUTS
  1352. *    ios2_SrcAddr - lower bound.
  1353. *    ios2_DstAddr - upper bound.
  1354. *
  1355. *   RESULTS
  1356. *    io_Error
  1357. *    ios2_WireError
  1358. *
  1359. *   EXAMPLE
  1360. *
  1361. *   NOTES
  1362. *
  1363. *   BUGS
  1364. *
  1365. *   SEE ALSO
  1366. *
  1367. ****************************************************************************
  1368. *
  1369. */
  1370.  
  1371. static BOOL CmdAddMulticastAddresses(struct IOSana2Req *request,
  1372.    struct DevBase *base)
  1373. {
  1374.    struct DevUnit *unit;
  1375.    UBYTE *lower_bound,*upper_bound;
  1376.  
  1377.    unit=(APTR)request->ios2_Req.io_Unit;
  1378.  
  1379.    lower_bound=request->ios2_SrcAddr;
  1380.    if(request->ios2_Req.io_Command==S2_ADDMULTICASTADDRESS)
  1381.       upper_bound=lower_bound;
  1382.    else
  1383.       upper_bound=request->ios2_DstAddr;
  1384.  
  1385.    if(!AddMulticastRange(unit,lower_bound,upper_bound,base))
  1386.    {
  1387.       request->ios2_Req.io_Error=S2ERR_NO_RESOURCES;
  1388.       request->ios2_WireError=S2WERR_GENERIC_ERROR;
  1389.    }
  1390.  
  1391.    /* Return */
  1392.  
  1393.    return TRUE;
  1394. }
  1395.  
  1396.  
  1397.  
  1398. /****** 3c589.device/S2_DELMULTICASTADDRESS ********************************
  1399. *
  1400. *   NAME
  1401. *    S2_DELMULTICASTADDRESS --
  1402. *
  1403. *   FUNCTION
  1404. *
  1405. *   INPUTS
  1406. *    ios2_SrcAddr - multicast address.
  1407. *
  1408. *   RESULTS
  1409. *    io_Error
  1410. *    ios2_WireError
  1411. *
  1412. *   EXAMPLE
  1413. *
  1414. *   NOTES
  1415. *
  1416. *   BUGS
  1417. *
  1418. *   SEE ALSO
  1419. *
  1420. ****************************************************************************
  1421. *
  1422. */
  1423.  
  1424. /****** 3c589.device/S2_DELMULTICASTADDRESSES ******************************
  1425. *
  1426. *   NAME
  1427. *    S2_DELMULTICASTADDRESSES --
  1428. *
  1429. *   FUNCTION
  1430. *
  1431. *   INPUTS
  1432. *    ios2_SrcAddr - lower bound.
  1433. *    ios2_DstAddr - upper bound.
  1434. *
  1435. *   RESULTS
  1436. *    io_Error
  1437. *    ios2_WireError
  1438. *
  1439. *   EXAMPLE
  1440. *
  1441. *   NOTES
  1442. *
  1443. *   BUGS
  1444. *
  1445. *   SEE ALSO
  1446. *
  1447. ****************************************************************************
  1448. *
  1449. */
  1450.  
  1451. static BOOL CmdDelMulticastAddresses(struct IOSana2Req *request,
  1452.    struct DevBase *base)
  1453. {
  1454.    struct DevUnit *unit;
  1455.    UBYTE *lower_bound,*upper_bound;
  1456.  
  1457.    unit=(APTR)request->ios2_Req.io_Unit;
  1458.  
  1459.    lower_bound=request->ios2_SrcAddr;
  1460.    if(request->ios2_Req.io_Command==S2_DELMULTICASTADDRESS)
  1461.       upper_bound=lower_bound;
  1462.    else
  1463.       upper_bound=request->ios2_DstAddr;
  1464.  
  1465.    if(!RemMulticastRange(unit,lower_bound,upper_bound,base))
  1466.    {
  1467.       request->ios2_Req.io_Error=S2ERR_BAD_STATE;
  1468.       request->ios2_WireError=S2WERR_BAD_MULTICAST;
  1469.    }
  1470.  
  1471.    /* Return */
  1472.  
  1473.    return TRUE;
  1474. }
  1475.  
  1476.  
  1477.  
  1478. /****i* 3c589.device/PutRequest ********************************************
  1479. *
  1480. *   NAME
  1481. *    PutRequest -- .
  1482. *
  1483. *   SYNOPSIS
  1484. *    PutRequest(port,request)
  1485. *
  1486. *    VOID PutRequest(struct MsgPort *,struct IORequest *);
  1487. *
  1488. *   FUNCTION
  1489. *
  1490. *   INPUTS
  1491. *    port
  1492. *    request
  1493. *
  1494. *   RESULT
  1495. *    None.
  1496. *
  1497. *   EXAMPLE
  1498. *
  1499. *   NOTES
  1500. *
  1501. *   BUGS
  1502. *
  1503. *   SEE ALSO
  1504. *
  1505. ****************************************************************************
  1506. *
  1507. */
  1508.  
  1509. VOID PutRequest(struct MsgPort *port,struct IORequest *request,
  1510.    struct DevBase *base)
  1511. {
  1512.    request->io_Flags&=~IOF_QUICK;
  1513.    PutMsg(port,(APTR)request);
  1514.  
  1515.    return;
  1516. }
  1517.  
  1518.  
  1519.  
  1520.